---
slug: /features/services
description: "Create services from containers at run-time"
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import VideoPlayer from '../../src/components/VideoPlayer';

# Ephemeral Services

Dagger Functions support service containers, enabling users to spin up additional services (as containers) and communicate with those services from their workflows.

This makes it possible to:
- Instantiate and return services from a Dagger Function, and then:
  - Use those services in other Dagger Functions (container-to-container networking)
  - Use those services from the calling host (container-to-host networking)
- Expose host services for use in a Dagger Function (host-to-container networking).

## Use cases

Some common scenarios for using services with Dagger Functions are:

- Running a database service for local storage or testing
- Running end-to-end integration tests against a service
- Running sidecar services

## Service containers

Services instantiated by a Dagger Function run in service containers, which have the following characteristics:

- Each service container has a canonical, content-addressed hostname and an optional set of exposed ports.
- Service containers are started just-in-time, de-duplicated, and stopped when no longer needed.
- Service containers are health checked prior to running clients.

### Example

Here is an example of a Dagger Function that returns an HTTP service, which can then be accessed from the calling host:

<Tabs groupId="language" queryString="sdk">
<TabItem value="go" label="Go">
```go file=./snippets/services-1/go/main.go
```
</TabItem>
<TabItem value="python" label="Python">
```python file=./snippets/services-1/python/main.py
```
</TabItem>
<TabItem value="typescript" label="TypeScript">
```typescript file=./snippets/services-1/typescript/index.ts
```
</TabItem>
<TabItem value="php" label="PHP">
```php file=./snippets/services-1/php/src/MyModule.php
```
</TabItem>
<TabItem value="java" label="Java">
```java file=./snippets/services-1/java/src/main/java/io/dagger/modules/mymodule/MyModule.java
```
</TabItem>
</Tabs>

See it in action:

<VideoPlayer src="/img/current_docs/features/service-container.webm" alt="Container to host networking" />

## Host services

This also works in the opposite direction: containers in Dagger Functions can communicate with services running on the host.

### Example

Here's an example of how a workflow running in a Dagger Function can access and query a MariaDB database service running on the host:

<Tabs groupId="language" queryString="sdk">
<TabItem value="go" label="Go">
```go file=./snippets/services-2/go/main.go
```
</TabItem>
<TabItem value="python" label="Python">
```python file=./snippets/services-2/python/main.py
```
</TabItem>
<TabItem value="typescript" label="TypeScript">
```typescript file=./snippets/services-2/typescript/index.ts
```
</TabItem>
<TabItem value="php" label="PHP">
```php file=./snippets/services-2/php/src/MyModule.php
```
</TabItem>
<TabItem value="java" label="Java">
```java file=./snippets/services-2/java/src/main/java/io/dagger/modules/mymodule/MyModule.java
```
</TabItem>
</Tabs>

See it in action:

<VideoPlayer src="/img/current_docs/features/service-host.webm" alt="Host to container networking" />

## Learn more

- [Use services as function arguments](../api/arguments.mdx#service-arguments)
- [Create and return services from a function](../api/services.mdx#expose-services-returned-by-functions-to-the-host)
- [Expose host services to a function](../api/services.mdx#expose-host-services-to-functions)
- [Start and stop services](../api/services.mdx#start-and-stop-services)
- [Persist service state](../api/services.mdx#persist-service-state)
